/**
 * 
 */
package com.googlecode.xcarve.netty.server;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.logging.LogLevel;
import io.netty.handler.logging.LoggingHandler;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import com.googlecode.xcarve.coder.NettyCodecAdapter;
import com.googlecode.xcarve.common.config.ServerConfig;
import com.googlecode.xcarve.exception.CarveException;
import com.googlecode.xcarve.netty.handler.NettyServerHandler;
import com.googlecode.xcarve.thread.DoveThreadFactory;
import com.googlecode.xcarve.transport.AbstractServer;

/**
 * @author duxinyun
 *
 */
public class NettyServer extends AbstractServer{
	
	private ServerBootstrap serverBootstrap;
	private static final NioEventLoopGroup bossGroup = new NioEventLoopGroup(0, 
			Executors.newCachedThreadPool(new DoveThreadFactory("dove server boss group")));
	private static final NioEventLoopGroup workGroup = new NioEventLoopGroup(0, 
			Executors.newCachedThreadPool(new DoveThreadFactory("dove server work group")));
	private volatile boolean isClosed = false;
	/**
	 * @param config
	 * @throws CarveException
	 */
	public NettyServer(ServerConfig serviceConfig) throws CarveException {
		super(serviceConfig);
	}


	@Override
	public void doBind() throws Throwable {
		final ExecutorService threadPool = Executors.newFixedThreadPool(4);
		serverBootstrap  = new ServerBootstrap();
		serverBootstrap.group(bossGroup, workGroup);
		serverBootstrap.channel(NioServerSocketChannel.class)
		.option(ChannelOption.SO_BACKLOG, 1000)
		.option(ChannelOption.SO_KEEPALIVE, true)
		.option(ChannelOption.SO_REUSEADDR, true)
		.option(ChannelOption.TCP_NODELAY, true)
		.handler(new LoggingHandler(LogLevel.INFO))
		.childHandler(new ChannelInitializer<SocketChannel>() {

			@Override
			protected void initChannel(SocketChannel ch) throws Exception {
				ch.pipeline().addLast(new LoggingHandler(LogLevel.DEBUG));
				NettyCodecAdapter coder = new NettyCodecAdapter("hessian");
				ch.pipeline().addLast("encoder",coder.getEncoderHandler());
				ch.pipeline().addLast("decoder",coder.getDecoderHandler());
				ch.pipeline().addLast(new NettyServerHandler(threadPool));
				
			}
			
		});
		serverBootstrap.bind(bindAddress).sync();
	}
	
	@Override
	public void send(Object message) throws CarveException {
	 
		
	}

	@Override
	public void send(Object message, boolean sent) throws CarveException {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void close() {
		isClosed = true;
		serverBootstrap.group().shutdownGracefully();
	}

	@Override
	public void close(int timeout) {
		
	}

	@Override
	public boolean isClosed() {
		return isClosed;
	}

 
	

}
